<script lang="ts" setup>
import type { SelectValue } from 'ant-design-vue/es/select';

import type { BaseOrgModel } from '#/api';

import { onMounted, reactive, ref } from 'vue';

import { isEmpty, isNullOrUnDef } from '@vben/utils';

import {
  Button,
  Card,
  Checkbox,
  Select,
  SelectOption,
  Space,
  Spin,
} from 'ant-design-vue'; // antd组件
// 引入VueBlocksTree组件
import VueBlocksTree from 'vue3-blocks-tree';

import { IotCustomersApi } from '#/api/iot/customers/iotCustomers';
import { PermCode } from '#/enums/perm';
import { useMessage } from '#/hooks/web/useMessage';
import { $t } from '#/locales';
import { findNodeByKey } from '#/utils/helper/treeHelper';

import 'vue3-blocks-tree/dist/vue3-blocks-tree.css';

const emit = defineEmits(['change', 'select', 'add', 'edit', 'delete']);

const permCode = PermCode.iot.customers;
const { createMessage, createConfirm } = useMessage();
const isHorizontal = ref<boolean>(false); // 是否垂直展示
const collapsable = ref<boolean>(false); // 折叠节点
const spinning = ref<boolean>(false); // 加载 ...
const labelClassName = ref<SelectValue>('bg-orange'); // 主题背景类名
const labelClassNameItem = reactive([
  { value: 'bg-primary', label: '主题背景' },
  { value: 'bg-white', label: '洁白无瑕' },
  { value: 'bg-orange', label: '金橙' },
  { value: 'bg-gold', label: '金光灿灿' },
  { value: 'bg-gray', label: '珊瑚灰' },
  { value: 'bg-lightpink', label: '姹紫嫣红' },
  { value: 'bg-chocolate', label: '黑朱古力' },
  { value: 'bg-tomato', label: '红彤彤' },
]);
const treeProps = { label: 'name', children: 'children', key: 'id' }; // 组件配置
const state = reactive({
  treeData: {
    name: '客户结构',
    expand: false,
    key: 0,
    children: [],
  },
  current: {} as BaseOrgModel.BaseOrgResultVO,
});

async function fetch() {
  spinning.value = true;
  try {
    state.treeData.children = (await IotCustomersApi.tree({})) as never[];
  } finally {
    spinning.value = false;
  }
}

// 切换主题颜色
function changeClassName(value: SelectValue) {
  labelClassName.value = value;
}

function changeDisplay() {
  emit('change', '1');
}

function nodeClick(e: Event, data: any) {
  e?.stopPropagation();
  if (data && data.id) {
    state.current = data;
    const node = findNodeByKey(data.id, state.treeData.children || []);
    const parent = findNodeByKey(node?.parentId, state.treeData.children || []);
    emit('select', parent, node);
  } else {
    state.current = { id: '', name: '根节点' };
    emit('select', { id: '', name: '根节点' });
  }
}

// 首次挂载
onMounted(async () => {
  await fetch();
});

function handleAdd() {
  if (state.current.id) {
    emit('add', findNodeByKey(state.current.id, state.treeData.children || []));
  } else {
    emit('add', findNodeByKey('0', state.treeData.children || []));
  }
}

function handleEdit() {
  if (state.current.id) {
    const current = findNodeByKey(
      state.current.id,
      state.treeData.children || [],
    );
    const parent = findNodeByKey(
      state.current.parentId,
      state.treeData.children || [],
    );
    emit('edit', parent, current);
  } else {
    createMessage.warn('请先选择节点');
  }
}

function handleDelete() {
  if (state.current.id) {
    batchDelete([state.current.id]);
  } else {
    createMessage.warn('请先选择节点');
  }
}

async function batchDelete(ids: string[]) {
  createConfirm({
    iconType: 'warning',
    content: `选中节点【${state.current.name}】及其子结点将被永久删除, 是否确定删除？`,
    onOk: async () => {
      try {
        await IotCustomersApi.remove(ids);
        await fetch();
        createMessage.success($t('common.tips.deleteSuccess'));
      } catch {}
    },
  });
}

defineExpose({
  fetch,
});
</script>
<template>
  <div class="overflow-hidden">
    <div class="mb-1">
      <Space>
        <Button
          v-hasAnyPermission="[permCode.switch]"
          type="primary"
          class="mr-2"
          @click="changeDisplay()"
        >
          切换
        </Button>
        <Button
          v-hasAnyPermission="[permCode.add]"
          class="mr-2"
          @click="handleAdd()"
        >
          新增客户
        </Button>
        <Button
          v-hasAnyPermission="[permCode.edit]"
          :disabled="
            isEmpty(state.current.id) || isNullOrUnDef(state.current.id)
          "
          class="mr-2"
          @click="handleEdit()"
        >
          编辑
        </Button>
        <Button
          v-hasAnyPermission="[permCode.delete]"
          class="mr-2"
          :disabled="
            isEmpty(state.current.id) || isNullOrUnDef(state.current.id)
          "
          @click="handleDelete()"
        >
          {{ $t('common.title.delete') }}
        </Button>
        <Button class="mr-2" @click="fetch()">
          {{ $t('common.redo') }}
        </Button>
      </Space>
      <Space class="mt-1">
        <!-- 垂直展示 -->
        <Checkbox v-model:checked="isHorizontal">垂直展示</Checkbox>
        <!-- 折叠节点 -->
        <Checkbox v-model:checked="collapsable">折叠节点</Checkbox>
        <!-- 主题背景 -->
        <Select
          :default-value="labelClassName"
          size="small"
          style="width: 120px"
          @change="changeClassName"
        >
          <SelectOption
            v-for="(item, index) in labelClassNameItem"
            :key="index"
            :value="item.value"
          >
            {{ item.label }}
          </SelectOption>
        </Select>
      </Space>
    </div>
    <Card>
      <div style="overflow: auto; text-align: center">
        <Spin :spinning="spinning" />
        <VueBlocksTree
          v-if="!spinning"
          :collapsable="collapsable"
          :data="state.treeData"
          :horizontal="isHorizontal"
          :label-class-name="labelClassName"
          :props="treeProps"
          @node-click="nodeClick"
        />
      </div>
    </Card>
  </div>
</template>

<style lang="less" scoped>
@bgColor: background-color;

.org-tree-node-label {
  white-space: nowrap;
}

:deep(.bg-primary) {
  @{bgColor}: hsl(var(--primary));
}

:deep(.bg-white) {
  @{bgColor}: white;
}

:deep(.bg-orange) {
  @{bgColor}: orange;
}

:deep(.bg-gold) {
  @{bgColor}: gold;
}

:deep(.bg-gray) {
  @{bgColor}: gray;
}

:deep(.bg-lightpink) {
  @{bgColor}: lightpink;
}

:deep(.bg-chocolate) {
  @{bgColor}: chocolate;
}

:deep(.bg-tomato) {
  @{bgColor}: tomato;
}
</style>
